﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Infrastructure.Annotations;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Delphi.Mimir.Data.Entities.Final.Mappings {
    class FinancialStatementMap : EntityTypeConfiguration<FinancialStatement> {
        public FinancialStatementMap() {
            /******************************************************************
            /* Table
            /*****************************************************************/
            ToTable("fin.eod_financial_statements");

            /******************************************************************
            /* Primary Key
            /*****************************************************************/
            HasKey(a => a.FinancialStatementId);

            /******************************************************************
            /* Index
            /*****************************************************************/
            // IX_FIS
            Property(a => a.SymbolId)
                .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute("IX_FIS", 1) { IsUnique = true }));
            Property(a => a.Date)
                .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute("IX_FIS", 2) { IsUnique = true }));
            Property(a => a.FrequencyId)
                .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute("IX_FIS", 3) { IsUnique = true }));

            /******************************************************************
            /* Relationships
            /*****************************************************************/
            // 1..n Symbol
            HasRequired<Symbol>(a => a.Symbol)
                .WithMany()
                .HasForeignKey(a => a.SymbolId);

            // 1..n Frequency
            HasRequired<Frequency>(a => a.Frequency)
                .WithMany()
                .HasForeignKey(a => a.FrequencyId);

            /******************************************************************
            /* Properties
            /*****************************************************************/
            // Income Statements
            Property(a => a.FinancialStatementId)
                .IsRequired()
                .HasColumnName("fis_id");

            Property(a => a.SymbolId)
                .IsRequired()
                .HasColumnName("fis_sym_id");

            Property(a => a.Date)
                .IsRequired()
                .HasColumnName("fis_dt");

            Property(a => a.FrequencyId)
                .IsRequired()
                .HasColumnName("fis_cat_id");

            Property(a => a.TotalRevenue)
                .IsOptional()
                .HasColumnName("fis_is_tot_rev");

            Property(a => a.CostOfGoodsSold)
                .IsOptional()
                .HasColumnName("fis_is_cogs");

            Ignore(a => a.GrossProfit);

            Property(a => a.ResearchAndDevelopment)
                .IsOptional()
                .HasColumnName("fis_is_rnd");

            Property(a => a.SellingGeneralAndAdministrative)
                .IsOptional()
                .HasColumnName("fis_is_sga");

            Property(a => a.NonRecurringOperatingExpense)
                .IsOptional()
                .HasColumnName("fis_is_nrec_op_ex");

            Property(a => a.OtherOperatingExpense)
                .IsOptional()
                .HasColumnName("fis_is_other_op_ex");

            Ignore(a => a.TotalOperatingExpense);

            Ignore(a => a.OperatingIncomeOrLoss);

            Property(a => a.TotalOtherIncomeOrExpensesNet)
                .IsOptional()
                .HasColumnName("fis_is_tot_other_inc_ex_net");

            Ignore(a => a.EarningsBeforeInterestOrTaxes);

            Property(a => a.InterestExpenses)
                .IsOptional()
                .HasColumnName("fis_is_int_ex_net");

            Ignore(a => a.EarningsBeforeTaxes);

            Property(a => a.IncomeTaxExpenses)
                .IsOptional()
                .HasColumnName("fis_is_inc_tax_ex");

            Property(a => a.MinorityInterest)
                .IsOptional()
                .HasColumnName("fis_is_min_int");

            Ignore(a => a.NetIncomeFromContinuingOps);

            Property(a => a.DiscontinuedOperations)
                .IsOptional()
                .HasColumnName("fis_is_disc_ops");

            Property(a => a.ExtraordinaryItems)
                .IsOptional()
                .HasColumnName("fis_is_extra");

            Property(a => a.EffectOfAccountingChanges)
                .IsOptional()
                .HasColumnName("fis_is_acct_chg");

            Property(a => a.OtherNonRecurringItems)
                .IsOptional()
                .HasColumnName("fis_is_other_nrec");

            Ignore(a => a.NetIncome);

            Property(a => a.PreferredStockAndOtherAdjustments)
                .IsOptional()
                .HasColumnName("fis_is_pref_other_adj");

            Ignore(a => a.NetIncomeAppicableToCommonShares);

            Property(a => a.HasIncomeStatementQualityIssues)
                .IsOptional()
                .HasColumnName("fis_is_quality_fg");

            Property(a => a.NetIncomeQualityAdjustment)
                .IsOptional()
                .HasColumnName("fis_is_quality_adj");

            // Balance Sheet
            Property(a => a.CashAndCashEquivalents)
                .IsOptional()
                .HasColumnName("fis_bs_ca_cash_eqiv");

            Property(a => a.ShortTermInvestments)
                .IsOptional()
                .HasColumnName("fis_bs_ca_st_inv");

            Property(a => a.NetReceivables)
                .IsOptional()
                .HasColumnName("fis_bs_ca_rec_net");

            Property(a => a.Inventory)
                .IsOptional()
                .HasColumnName("fis_bs_ca_invtry");

            Property(a => a.OtherCurrentAssets)
                .IsOptional()
                .HasColumnName("fis_bs_ca_other");

            Ignore(a => a.TotalCurrentAssets);

            Property(a => a.LongTermInvestments)
                .IsOptional()
                .HasColumnName("fis_bs_nca_lt_inv");

            Property(a => a.PropertyPlantAndEquipment)
                .IsOptional()
                .HasColumnName("fis_bs_nca_ppe");

            Property(a => a.Goodwill)
                .IsOptional()
                .HasColumnName("fis_bs_nca_gwill");

            Property(a => a.IntangibleAssets)
                .IsOptional()
                .HasColumnName("fis_bs_nca_intang_asst");

            Property(a => a.AccumulatedAmortization)
                .IsOptional()
                .HasColumnName("fis_bs_nca_accum_amort");

            Property(a => a.OtherNonCurrentAssets)
                .IsOptional()
                .HasColumnName("fis_bs_nca_other");

            Property(a => a.DeferredLongTermAssetCharges)
                .IsOptional()
                .HasColumnName("fis_bs_nca_dfrd_lt_asst_chrg");

            Ignore(a => a.TotalNonCurrentAssets);

            Ignore(a => a.TotalAssets);

            Property(a => a.AccountsPayable)
                .IsOptional()
                .HasColumnName("fis_bs_cl_payb_net");

            Property(a => a.ShortAndCurrentLongTermDebt)
                .IsOptional()
                .HasColumnName("fis_bs_cl_st_curr_lt_debt");

            Property(a => a.OtherCurrentLiabilities)
                .IsOptional()
                .HasColumnName("fis_bs_cl_other");

            Ignore(a => a.TotalCurrentLiabilities);

            Property(a => a.LongTermDebt)
                .IsOptional()
                .HasColumnName("fis_bs_ncl_lt_debt");

            Property(a => a.OtherNonCurrentLiabilities)
                .IsOptional()
                .HasColumnName("fis_bs_ncl_other");

            Property(a => a.DeferredLongTermLiabilitiesCharges)
                .IsOptional()
                .HasColumnName("fis_bs_ncl_dfrd_lt_liab_chrg");

            Property(a => a.AccumulatedMinorityInterest)
                .IsOptional()
                .HasColumnName("fis_bs_ncl_min_int");

            Property(a => a.NegativeGoodwill)
                .IsOptional()
                .HasColumnName("fis_bs_ncl_neg_gwill");

            Ignore(a => a.TotalNonCurrentLiabilities);

            Ignore(a => a.TotalLiabilities);

            Property(a => a.MiscStocksOptionsWarrants)
                .IsOptional()
                .HasColumnName("fis_bs_eq_st_opt_wrnt");

            Property(a => a.RedeemablePreferredStock)
                .IsOptional()
                .HasColumnName("fis_bs_eq_redeem_prfd_st");

            Property(a => a.PreferredStock)
                .IsOptional()
                .HasColumnName("fis_bs_eq_prfd_st");

            Property(a => a.CommonStock)
                .IsOptional()
                .HasColumnName("fis_bs_eq_comn_st");

            Property(a => a.RetainedEarnings)
                .IsOptional()
                .HasColumnName("fis_bs_eq_ret_earn");

            Property(a => a.TreasuryStock)
                .IsOptional()
                .HasColumnName("fis_bs_eq_try_st");

            Property(a => a.CapitalSurplus)
                .IsOptional()
                .HasColumnName("fis_bs_eq_cap_splus");

            Property(a => a.OtherStockholderEquity)
                .IsOptional()
                .HasColumnName("fis_bs_eq_other");

            Ignore(a => a.TotalStockholderEquity);

            Property(a => a.NetTangibleAssets)
                .IsOptional()
                .HasColumnName("fis_bs_tng_asst_net");

            // Cash Flow
            Property(a => a.Depreciation)
                .IsOptional()
                .HasColumnName("fis_cf_op_depr");

            Property(a => a.AdjustmentsToNetIncome)
                .IsOptional()
                .HasColumnName("fis_cf_op_ni_adj");

            Property(a => a.ChangesInAccountReceivables)
                .IsOptional()
                .HasColumnName("fis_cf_op_rec_chg");

            Property(a => a.ChangesInLiabilities)
                .IsOptional()
                .HasColumnName("fis_cf_op_liab_chg");

            Property(a => a.ChangesInInventories)
                .IsOptional()
                .HasColumnName("fis_cf_op_invtry_chg");

            Property(a => a.ChangesInOtherOperatingActivities)
                .IsOptional()
                .HasColumnName("fis_cf_op_other_chg");

            Ignore(a => a.TotalCashFlowFromOperatingActivities);

            Property(a => a.CapitalExpenditure)
                .IsOptional()
                .HasColumnName("fis_cf_inv_cap_ex");

            Property(a => a.Investments)
                .IsOptional()
                .HasColumnName("fis_cf_inv");

            Property(a => a.OtherCashFlowFromInvestingActivities)
                .IsOptional()
                .HasColumnName("fis_cf_inv_other");

            Ignore(a => a.TotalCashFlowFromInvestingActivities);

            Property(a => a.DividendsPaid)
                .IsOptional()
                .HasColumnName("fis_cf_fin_div");

            Property(a => a.SalePurchaseOfStock)
                .IsOptional()
                .HasColumnName("fis_cf_fin_sale_purch_st");

            Property(a => a.NetBorrowings)
                .IsOptional()
                .HasColumnName("fis_cf_fin_borrow_net");

            Property(a => a.OtherCashFlowFromFinancingActivities)
                .IsOptional()
                .HasColumnName("fis_cf_fin_other");

            Ignore(a => a.TotalCashFlowFromFinancingActivities);

            Property(a => a.EffectOfExchangeRateChanges)
                .IsOptional()
                .HasColumnName("fis_cf_fx_chg");

            Property(a => a.ChangeInCashAndCashEquivalents)
                .IsOptional()
                .HasColumnName("fis_cf_cash_eqiv_chg");
        }
    }
}
